package cn.com.haopy.yue.ai.wx.web;


import cn.com.haopy.yue.ai.comm.service.HumanApiService;
import cn.com.haopy.yue.ai.core.system.SystemConfig;
import cn.com.haopy.yue.ai.core.utils.ResponseUtil;
import cn.com.haopy.yue.ai.db.entity.arisk.AIRiskUserHumanQueue;
import cn.com.haopy.yue.ai.db.entity.arisk.AIRiskUserHumanSource;
import cn.com.haopy.yue.ai.db.service.hos.AIRiskUserHumanQueueService;
import cn.com.haopy.yue.ai.db.service.hos.AIRiskUserHumanSourceService;
import cn.com.haopy.yue.ai.wx.annotation.LoginUser;
import cn.com.haopy.yue.ai.wx.service.WxHumanSignService;
import cn.com.haopy.yue.ai.wx.web.base.BaseWxController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * 登录
 */
@RestController
@RequestMapping("/haopyYueAi/human")
@RequiredArgsConstructor
@Slf4j
@Api(tags = "数字人签名")
public class WxHumanSignController extends BaseWxController {
    @Autowired
    private HumanApiService humanApiService;

    @Autowired
    private AIRiskUserHumanQueueService riskUserHumanQueueService;


    @Autowired
    private AIRiskUserHumanSourceService riskUserHumanSourceService;

    @Autowired
    private WxHumanSignService wxHumanSignService;


    /**
     * 获取Token（前后端通用）
     * <p>
     * 通过HTTP GET请求调用远程接口【/guiji/createSig】获取Token签名。
     * </p>
     *
     * @return 使用ResponseUtil封装后的签名信息
     * @throws Exception 请求过程中可能抛出的异常
     */
    @GetMapping("/sign")
    @ApiOperation(value = "签名")
    public Object sign() throws Exception {
        return humanApiService.sign();
    }

    /**
     * 关闭指定uuid的会话
     * <p>
     * 此接口用于关闭指定UUID对应的会话，需要传入会话标识uuid和可选的token值。
     * </p>
     *
     * @param sign 可选的token，默认值为空字符串
     * @param uuid 必传的会话uuid
     * @return 通过远程接口调用返回的结果
     * @throws Exception 处理过程中可能抛出的异常
     */
    @GetMapping("/sessionStop")
    @ApiOperation(value = "关闭指定uuid的会话")
    public Object sessionStop(@LoginUser Integer userId, @RequestParam(required = true, defaultValue = "") String sign,
                              @RequestParam(required = true) String uuid) throws Exception {
        if (Objects.isNull(userId)) {
            return ResponseUtil.unlogin();
        }
        return humanApiService.sessionStop(sign, uuid);
    }

    /**
     * 获取可以使用的通道数和正在使用的通道数
     * <p>
     * 调用远程接口【/guiji/getconcurrentNumber】，传入可选的token，获取当前的通道使用情况。
     * </p>
     *
     * @param sign 可选的sign，数字人签名默认值为空字符串
     * @return 返回调用远程接口获取的结果，包含通道数信息
     * @throws Exception 请求过程中可能抛出的异常
     */
    @GetMapping("/getConcurrentNumber")
    @ApiOperation(value = "获取可以使用的通道数和正在使用的通道数")
    public Object getconcurrentNumber(@LoginUser Integer userId, @RequestParam(required = true, defaultValue = "") String sign) throws Exception {
        if (Objects.isNull(userId)) {
            return ResponseUtil.unlogin();
        }
        return humanApiService.getconcurrentNumber(sign);
    }

    /**
     * 获取当前的会话列表
     * <p>
     * 此接口通过调用【/guiji/getconcurrentList】远程接口，查询当前所有正在运行的会话，
     * 可选参数token用于身份校验或其他用途。
     * </p>
     *
     * @param sign 可选的token，默认值为空字符串
     * @return 返回当前会话列表的查询结果
     * @throws Exception 请求过程中可能抛出的异常
     */
    @GetMapping("/getConcurrentList")
    @ApiOperation(value = "获取当前的会话的列表")
    public Object getconcurrentList(@LoginUser Integer userId, @RequestParam(required = true, defaultValue = "") String sign) throws Exception {
        if (Objects.isNull(userId)) {
            return ResponseUtil.unlogin();
        }
        return humanApiService.getconcurrentList(sign);
    }

    /**
     * 一口气关闭所有会话
     * <p>
     * 该接口用于一次性关闭所有会话，调用【/guiji/distroyCallSessionsByAppId】接口，
     * 可选参数token用于身份识别。
     * </p>
     *
     * @param sign 可选的token，默认值为空字符串
     * @return 返回关闭所有会话的操作结果
     * @throws Exception 请求处理过程中可能抛出的异常
     */
    @GetMapping("/distroyCallSessionsByAppId")
    @ApiOperation(value = "一口气关闭所有会话")
    public Object distroyCallSessionsByAppId(@LoginUser Integer userId, @RequestParam(required = true, defaultValue = "") String sign) throws Exception {
        if (Objects.isNull(userId)) {
            return ResponseUtil.unlogin();
        }
        return humanApiService.distroyCallSessionsByAppId(sign);
    }


    @GetMapping("/myJoinQueue")
    @ApiOperation(value = "获取我的排队")
    public Object myJoinQueue(@LoginUser Integer userId) {
        if (Objects.isNull(userId)) {
            return ResponseUtil.unlogin();
        }
        return ResponseUtil.ok(riskUserHumanQueueService.getQueueByUserId(userId));
    }


    @GetMapping("/outQueue")
    @ApiOperation(value = "退出排队")
    public Object outQueue(@LoginUser Integer userId) {
        if (Objects.isNull(userId)) {
            return ResponseUtil.unlogin();
        }
        AIRiskUserHumanQueue humanQueue = riskUserHumanQueueService.getQueueByUserId(userId);
        if (Objects.nonNull(humanQueue)) {
            humanQueue.setIsAllot(Boolean.TRUE);
            humanQueue.setIsCancel(Boolean.TRUE);
        }
        riskUserHumanQueueService.updateById(humanQueue);

        return ResponseUtil.ok();
    }


    @GetMapping("/joinQueue")
    @ApiOperation(value = "加入排队")
    public Object joinQueue(@LoginUser Integer userId) {
        if (Objects.isNull(userId)) {
            return ResponseUtil.unlogin();
        }
        AIRiskUserHumanQueue humanQueue = riskUserHumanQueueService.getQueueByUserId(userId);

        if (Objects.isNull(humanQueue)) {
            humanQueue = new AIRiskUserHumanQueue();
            humanQueue.setUserId(userId);
            humanQueue.setIsAllot(false);

            riskUserHumanQueueService.save(humanQueue);
        }


        Map<String, Object> mapData = new HashMap<>();
        //总人数
        Integer sumCount = riskUserHumanQueueService.queueCount();
        Integer myCount = riskUserHumanQueueService.myQueueIndex(humanQueue.getId()) + 1;
        mapData.put("allCount", sumCount);
        mapData.put("myCount", myCount);

        return ResponseUtil.ok(mapData);

    }

    @GetMapping("/freeSource")
    @ApiOperation(value = "空闲资源信息")
    public Object freeSource(@LoginUser Integer userId) {
        if (Objects.isNull(userId)) {
            return ResponseUtil.unlogin();
        }
        //使用中的资源
        Integer countUsing = riskUserHumanSourceService.getCountUseIng();
        //全部资源
        Integer count = SystemConfig.getSystemRiskHumanSourceCount();
        //排队人数
        Integer countQueue = riskUserHumanQueueService.queueCount();

        Map<String, Object> data = new HashMap<>();
        data.put("countUsing", countUsing);
        data.put("count", count);
        data.put("countQueue", countQueue);


        return ResponseUtil.ok(data);

    }

    @GetMapping("/useSource")
    @ApiOperation(value = "使用资源通道")
    public Object useSource(@LoginUser Integer userId,
                            @RequestParam(required = false) @ApiParam("排队列ID") Integer queueId,
                            @RequestParam(required = false) @ApiParam("资源通道ID") String sourceId,
                            @RequestParam(required = false) @ApiParam("签名") String sign) throws Exception {
        if (Objects.isNull(userId)) {
            return ResponseUtil.unlogin();
        }


        return wxHumanSignService.useSource(userId, queueId, sourceId, sign);

    }


    @GetMapping("/endSource")
    @ApiOperation(value = "结束使用资源通道")
    public Object endSource(@LoginUser Integer userId,
                            @RequestParam(required = false) @ApiParam("资源通道ID") String sourceId,
                            @RequestParam(required = false) @ApiParam("签名") String sign) {
        if (Objects.isNull(userId)) {
            return ResponseUtil.unlogin();
        }

        AIRiskUserHumanSource humanSource = riskUserHumanSourceService.getByUserSourceId(userId, sourceId, sign);
        if (Objects.nonNull(humanSource)) {
            humanSource.setFinishTime(LocalDateTime.now());
            humanSource.setIsFinish(Boolean.TRUE);
            riskUserHumanSourceService.updateById(humanSource);
        } else {
            System.out.println("找不到：" + sourceId);
        }

        return ResponseUtil.ok();
    }


}